<template>
  <div class="result" v-if="start">
    <InfoCard :title="title">
      <template v-slot:content v-if="loading">
        <van-loading size="32px" vertical color="#6C9CFF" text-color="#333" class="result__loading">
          {{ loadingText }}
        </van-loading>
      </template>
      <template v-slot:content v-else>
        <Detail />
      </template>
    </InfoCard>
  </div>
</template>

<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
import eventBus, { eventNames } from '@/utils/event-bus';
import type { ConfigItem, TesterType } from '@/types/tester'
import { handleResult } from './lib/handle-result';
import { dcConfig, processDCResult } from './lib/dc-config';
import { loopConfig } from './lib/loop-config';
import { insulationConfig } from './lib/insulation-config';
import { mechanicalConfig } from './lib/mechanical-config';
import { lightningConfig } from './lib/lightning-config';
import { dielectricConfig } from './lib/dielectric-config';
import { flattenedWithPath } from './lib/relay-config';
import { infraredConfig } from './lib/infrared-config';
import { log, hex2Buffer, buffer2String } from '@/utils';
import {
  dcResistance,
  loopResistance,
  insulation,
  infrared,
  mechanical,
  dielectric,
  lightning,
  relay
} from '@/modules/const';
import InfoCard from '@/components/info-card';
import Detail from '@/business/details';
import { writeStopCode, writeCurrentCode } from '@/modules/bluetooth';

@Component({
  name: 'Result',
  components: {
    InfoCard,
    Detail
  }
})
export default class Result extends Vue {

  private title = '测试结果';
  private loading: boolean = false;
  private stopText = '停止中...';
  private workingText = '持续测试中...'
  private currentText = '获取数据中...';
  private historyDataText = '获取历史数据中...';
  private loadingText = '';
  private start = false;

  // 当前测试仪
  private get tester() {
    return this.$store.state.tester as TesterType;
  }

  // 先停止测试，再获取数据
  private get isStopFirst() {
    return [relay].includes(this.tester);
  }

  // 通过TCP服务连接获取数据的情况
  private get isTCPServer() {
    return [infrared].includes(this.tester);
  }

  mounted() {
    eventBus.$on(eventNames.receiveData, (hexData: string) => {
      this.analyzeData(hexData);
      if (!this.isStopFirst && !this.isTCPServer) {
        // 1秒后自动停止，因为蓝牙模型获取测量数据需要发送确认指令
        setTimeout(() => {
          writeStopCode();
        }, 1000)
      } else {
        this.loading = false;
      }
    });
    eventBus.$on(eventNames.startTest, (state: string) => {
      // if (state === "02") {
      //   this.$toast('设备忙碌，请先停止');
      //   return
      // }
      this.start = true;
      this.loading = true;
      this.loadingText = this.workingText;
      this.$store.dispatch('setResult', []);
    });
    eventBus.$on(eventNames.receiveHistoryData, () => {
      this.start = true;
      this.loading = true;
      this.loadingText = this.historyDataText;
      this.$store.dispatch('setResult', []);
    });
    eventBus.$on(eventNames.stopTest, () => {
      if (this.isStopFirst) {
        // 先停止测试，再获取数据
        this.runStopCommand();
      } else {
        // 先获取数据再停止测试
        this.runCurrentCommand();
      }
    });
    eventBus.$on(eventNames.receiveStop, () => {
      if (this.isStopFirst) {
        setTimeout(() => {
          this.runCurrentCommand();
        }, 800)
      } else {
        this.loading = false;
      }
    })
    eventBus.$on(eventNames.writeHexCmdFailure, (err: string) => {
      this.$toast({ message: `发送蓝牙指令失败，请检查蓝牙连接\n${err}` });
      this.$store.dispatch('setResult', []);
      this.loading = false;
    })
    eventBus.$on(eventNames.bluetoothDisconnect, (err: BLECentralPlugin.BLEError) => {
      this.$toast({ message: `蓝牙连接断开\n${err.errorMessage}` });
      // 蓝牙断开时，正在测试中，清空数据
      if (this.loading) {
        this.$store.dispatch('setResult', []);
        this.loading = false;
      }
    })
  }

  runStopCommand() {
    this.loading = true;
    this.loadingText = this.stopText;
    writeStopCode();
  }

  runCurrentCommand() {
    this.loading = true;
    this.loadingText = this.currentText;
    writeCurrentCode();
  }

  // 解析当前试验数据
  analyzeData(hexData: string) {
    this.loading = true;
    let result: Partial<ConfigItem>[] = [];
    switch (this.tester) {
      case dcResistance:
        result = processDCResult(handleResult(hexData, dcConfig));
        break;
      case loopResistance:
        result = handleResult(hexData, loopConfig);
        break;
      case insulation:
        result = handleResult(hexData, insulationConfig);
        break;
      case mechanical:
        result = handleResult(hexData, mechanicalConfig);
        break;
      case lightning:
        result = handleResult(hexData, lightningConfig);
        break;
      case relay:
        const buffer = hex2Buffer(hexData);
        const string = buffer2String(buffer);
        result = flattenedWithPath(string)
        break;
      case dielectric:
        result = handleResult(hexData, dielectricConfig);
        break;
      case infrared:
        result = handleResult(hexData, infraredConfig);
        break;
    }
    console.log(result)
    this.$store.dispatch('setResult', result);
    log('蓝牙解析结果：', result);
    this.loading = false;
  }

  destroyed() {
    eventBus.$off(eventNames.receiveData);
    eventBus.$off(eventNames.startTest);
    eventBus.$off(eventNames.receiveStop);
    eventBus.$off(eventNames.stopTest);
    eventBus.$off(eventNames.receiveHistoryData);
    eventBus.$off(eventNames.writeHexCmdFailure);
    eventBus.$off(eventNames.bluetoothDisconnect);
  }
}
</script>

<style lang="scss" scoped>
.result {
  margin: 8px;
  padding-bottom: 60px;

  &__loading {
    padding: 100px 0;
  }

  &__data {
    color: $font-color;
    font-size: 16px;
    text-align: center;
    display: flex;
    padding-top: 10px;
    opacity: 0.84;
    flex-wrap: wrap;
    margin-bottom: 20px;
    justify-content: center;

    &--more {
      width: calc(100% - 30px);
    }
  }

  &__data-item {
    width: 33%;
    margin-bottom: 8px;
  }

  &__data-label {
    color: #666666;
    padding: 4px 0;
    font-size: 14px;
  }

  &__time {
    color: rgba(179, 179, 179, 0.84);
    font-size: 14px;
    position: absolute;
    bottom: 12px;
    text-align: center;
    left: 0;
    right: 0;
  }
}
</style>
